﻿#include <iostream>
#include <assert.h>
#include <map>
#include <sstream>
#include "threadfactory.h"

/*********************************************************************
* 线程工厂使用示例：
* 线程工厂相对会复杂一点，分为两部分，一部分为线程执行体， 一部分为任务执行体
*********************************************************************/
//实现自己的工厂
class MyJob : public BaseTaskThread<bool, int>
{
public:
	MyJob(CThreadFactoryBase& factory, int start) :BaseTaskThread(factory), m_idx(start) {}
	void Run()override
	{
		while (!IsStop())
		{
			ValuePtrType task;
			if (GetJob(task))
			{
				(*task)(m_idx++);
			}
		}

	}
	int m_idx = 0;
};


class BatchSql : public BaseDataThread<int, std::string>
{
public:
	BatchSql(CThreadFactoryBase& factory) :BaseDataThread(factory) {}
	void Run()override
	{
		while (!IsStop())
		{
			ValuePtrType task;
			if (GetJob(task, std::chrono::seconds(1)))
			{
				//std::string strSql = std::get<0>(task->data);
				m_vecSqlList.push_back(task);
			}
			else
			{
				for (auto& item : m_vecSqlList)
				{
					std::cout << "超过1秒未接收到数据，执行脚本" << std::get<0>(item->data) << std::endl;
					item->res.set_value(1);
				}
				m_vecSqlList.clear();
			}
			if (m_vecSqlList.size() == 10)
			{
				for (auto& item : m_vecSqlList)
				{
					std::cout << "批量执行脚本" << std::get<0>(item->data) << std::endl;
					item->res.set_value(1);
				}
				m_vecSqlList.clear();
			}
		}

	}
	std::vector<ValuePtrType> m_vecSqlList;
};



bool Func3(int i)
{
	std::cout << i * 100 << "-->" << "测试函数" << std::endl;
	return true;
}

class PrintTest {
public:
	bool Func1(int i, const std::string& msg)
	{
		std::cout << i << "-->" << msg << std::endl;
		return true;
	}

	bool Func2(int i)
	{
		std::cout << i << "-->" << "测试成员函数" << std::endl;
		return false;
	}
};

int main()
{
	CThreadFactory<MyJob> fact;
	fact.Start(2, 100);

	for (size_t i = 0; i < 100; i++)
	{
		fact.Push([](int idx) {std::cout << "测试lambda表达式:" << idx << std::endl; return true; });
	}

	// //测试函数
	auto ret = fact.Push(Func3);
	std::cout << "获取到结果:" << ret.get() << std::endl;

	// //将本地参数传入，与线程传入参数一起计算
	std::string strVal = "Hello";
	int add = 1000;
	auto ret2 = fact.Push(
	[strVal,add](int idx) {

		std::cout << "测试lambda表达式:" << strVal << "-->" << idx << std::endl;
		return true;
	});
	std::cout << "获取到结果2:" << ret2.get() << std::endl;

	PrintTest p;
	//成员函数
	fact.Push(std::bind(&PrintTest::Func2, &p, std::placeholders::_1));
	//成员函数
	fact.Push(std::bind(&PrintTest::Func1, &p, std::placeholders::_1, "混合参数"));


	CThreadFactory<BatchSql> sqlExec;
	sqlExec.Start(1);
	for (size_t i = 0; i < 100; i++)
	{
		std::stringstream ss;
		ss << "insert into tabName(id, name) value(";
		ss << i;
		ss << ",'张三')";
		sqlExec.Push(ss.str());
	}
	 
	auto ft = sqlExec.Push("测试同步执行");
	std::cout << "执行结果" << ft.get() << std::endl;

	std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    return 0;
}